package com.dbflow5.query;

import com.dbflow5.query.property.IProperty;
import com.dbflow5.query.property.Property;
import ohos.utils.Pair;


public class SQLite{
    /**
     * Starts a Select statement on the IProperty.
     * @param properties The properties/columns to SELECT.
     * @return A beginning of the SELECT statement.
     */
    public static Select select(IProperty<?>... properties) {
        return new Select(properties);
    }

    /**
     * Starts a new SELECT COUNT(property1, property2, propertyn) (if properties specified) or
     * SELECT COUNT(*).
     *
     * @param properties Optional, if specified returns the count of non-null ROWs from a specific single/group of columns.
     * @return A new select statement SELECT COUNT(expression)
     */
    public static Select selectCountOf(IProperty<?>... properties) {
        return new Select(Method.count(properties));
    }

    /**
     * Starts a Update statement on the specified table.
     * @param table    The tablet to update.
     * @return A new UPDATE statement.
     */
    public static <T> Update<T> update(Class<T> table) {
        return new Update<>(table);
    }

    public static <T> Insert<T> insertInto(Class<T> clazz) {
        return insert(clazz, new Property<?>[]{});
    }

    @SafeVarargs
    public static <T> Insert<T> insert(Class<T> table, Pair<IProperty<?>, ?>... columnValues) {
        return new Insert<>(table).columnValues(columnValues);
    }

    public static <T> Insert<T> insert(Class<T> table, SQLOperator... operators) {
        return new Insert<>(table).columnValues(operators);
    }

    public static <T> Insert<T> insert(Class<T> table) {
        return new Insert<>(table);
    }

    /**
     * Starts a Insert statement on the table.
     * @param table    The table to insert.
     * @param columns columns
     * @return A new INSERT statement.
     */
    public static <T> Insert<T> insert(Class<T> table, Property<?>... columns) {
        return new Insert<>(table, columns);
    }

    /**
     * Begins a DELETE statement.
     * @return Begins a DELETE statement.
     */
    public static Delete delete() {
        return new Delete();
    }

    /**
     * Starts a DELETE statement on the specified table.
     *
     * @param table    The table to delete from.
     * @return A [From] with specified DELETE on table.
     */
    public static <T> From<T> delete(Class<T> table) {
        return delete().from(table);
    }

    /**
     * Starts an INDEX statement on specified table.
     *
     * @param name The name of the index.
     * @param table table
     * @return A new INDEX statement.
     */
    public static <T> Index<T> index(String name, Class<T> table) {
        return new Index<>(name, table);
    }

    /**
     * Starts a TRIGGER statement.
     *
     * @param name The name of the trigger.
     * @return A new TRIGGER statement.
     */
    public static Trigger createTrigger(String name) {
        return Trigger.create(name);
    }

    /**
     * Starts a temporary TRIGGER statement.
     *
     * @param name The name of the trigger.
     * @return A new TEMPORARY TRIGGER statement.
     */
    public static Trigger createTempTrigger(String name) {
        return Trigger.create(name).temporary();
    }

    /**
     * Starts a CASE statement.
     *
     * @param operator The condition to check for in the WHEN.
     * @return A new [CaseCondition].
     */
    public static <T> CaseCondition<T> caseWhen(SQLOperator operator) {
        return new Case<T>().whenever(operator);
    }

    /**
     * Starts an efficient CASE statement. The value passed here is only evaulated once. A non-efficient
     * case statement will evaluate all of its [SQLOperator].
     *
     * @param caseColumn The value
     * @return Case
     */
    public static <TReturn> Case<TReturn> _case(Property<TReturn> caseColumn) {
        return new Case<>(caseColumn);
    }

    /**
     * Starts an efficient CASE statement. The value passed here is only evaulated once. A non-efficient
     * case statement will evaluate all of its [SQLOperator].
     *
     * @param caseColumn The value
     * @return Case
     */
    public static <TReturn> Case<TReturn> _case(IProperty<?> caseColumn) {
        return new Case<>(caseColumn);
    }
}